const path = require('path');
const webpack = require('webpack');
const TerserPlugin = require('terser-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const { VueLoaderPlugin } = require('vue-loader');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const dotenv = require('dotenv');
const fs = require('fs');

const isProd = process.env.NODE_ENV === 'production';

// 加载环境变量
const loadEnv = () => {
  const envFiles = [
    /** default file */ `.env`,
    /** mode file */ `.env.${process.env.NODE_ENV}`,
    /** local file */ `.env.local`,
    /** mode local file */ `.env.${process.env.NODE_ENV}.local`,
  ];

  const env = {};

  envFiles.forEach((file) => {
    if (fs.existsSync(file)) {
      Object.assign(env, dotenv.parse(fs.readFileSync(file)));
    }
  });

  return env;
};

const env = loadEnv();

module.exports = {
  mode: isProd ? 'production' : 'development',
  entry: './src/main.ts',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: isProd ? 'js/[name].[contenthash:8].js' : '[name].js',
    chunkFilename: isProd ? 'js/[name].[contenthash:8].js' : '[name].js',
    clean: true,
    publicPath: '/'
  },
  optimization: {
    minimize: isProd,
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          compress: {
            drop_console: isProd, // 生产环境下移除 console
            drop_debugger: isProd
          }
        }
      })
    ],
    splitChunks: {
      chunks: 'all',
      minSize: 20000,
      maxSize: 244000,
      cacheGroups: {
        vendor: {
          name: 'vendors',
          test: /[\\/]node_modules[\\/]/,
          priority: -10,
          chunks: 'initial'
        },
        common: {
          name: 'common',
          minChunks: 2,
          priority: -20,
          chunks: 'initial',
          reuseExistingChunk: true
        }
      }
    },
    runtimeChunk: 'single'
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.vue'],
    alias: {
      '@': path.resolve(__dirname, 'src'),
      'vue': '@vue/runtime-dom'
    }
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              cacheDirectory: true // 启用缓存
            }
          }
        ],
        exclude: /node_modules/
      },
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      },
      {
        test: /\.css$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1
            }
          },
          'postcss-loader'
        ]
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        type: 'asset',
        parser: {
          dataUrlCondition: {
            maxSize: 4 * 1024 // 4kb
          }
        },
        generator: {
          filename: 'images/[name].[hash:8][ext]'
        }
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        type: 'asset',
        parser: {
          dataUrlCondition: {
            maxSize: 4 * 1024 // 4kb
          }
        },
        generator: {
          filename: 'fonts/[name].[hash:8][ext]'
        }
      }
    ]
  },
  plugins: [
    new VueLoaderPlugin(),
    new HtmlWebpackPlugin({
      template: './index.html',
      minify: isProd ? {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
      } : false
    }),
    new webpack.DefinePlugin({
      'process.env': JSON.stringify(env),
      'import.meta.env': JSON.stringify(env),
      __VUE_OPTIONS_API__: true,
      __VUE_PROD_DEVTOOLS__: false,
      __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: false
    }),
    // 生产环境启用 gzip 压缩
    isProd && new CompressionPlugin({
      test: /\.(js|css|html|svg)$/,
      threshold: 10240 // 10kb
    }),
    // 分析打包结果
    process.env.ANALYZE && new BundleAnalyzerPlugin()
  ].filter(Boolean),
  devServer: {
    historyApiFallback: true,
    hot: true,
    port: 8080,
    proxy: {
      '/api': {
        target: env.VITE_APP_PROXY_TARGET,
        changeOrigin: true,
        pathRewrite: { '^/api': '' }
      }
    }
  },
  devtool: isProd ? false : 'eval-source-map',
  stats: {
    modules: false,
    children: false
  },
  performance: {
    hints: false
  }
};